package org.security.handler.filter;

import com.alibaba.fastjson.JSONObject;
import org.pmw.tinylog.Logger;
import org.security.config.FreeProperties;
import org.security.config.web.AbstractFreeSecurityWebConfig;
import org.security.config.web.UrlPermissionConfig;
import org.security.exception.CustomException;
import org.security.handler.BeforeFilterHandler;
import org.security.handler.filter.able.DefaultLoginVaildAble;
import org.security.jwt.JwtUtil;
import org.security.jwt.UserInfo;
import org.security.localstore.UserBase;
import org.security.localstore.UserContext;
import org.security.util.RequestUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.time.Instant;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

import static org.security.enums.CustomExceptionType.*;

/**
 * 登录认证
 * @author jt
 * @date 2024/7/19 22:04
 */
@Component
public class UsernamePasswordAuthoricationHandler implements BeforeFilterHandler {


    @Autowired
    private FreeProperties properties;

    @Autowired
    private DefaultLoginVaildAble loginValidAble;

    @Autowired
    private AbstractFreeSecurityWebConfig config;


    @Override
    public Integer getIndex() {
        return 10;
    }

    @Override
    public String getName() {
        return "UsernamePasswordAuthoricationHandler";
    }

    @Override
    public void doFilter(HttpServletRequest request, HttpServletResponse response) {
        String token = request.getHeader(properties.getTokenKey());

        JSONObject body = RequestUtil.getBody(request);
        if(token!=null){
            //执行判断token逻辑
            if(loginValidAble.checkTokenValid(token)){
                JwtUtil.JwtPayloadInfo payloadInfo = JwtUtil.verify(token);
                UserInfo userInfo =new UserBase();
                userInfo.setToken(token);
                BeanUtils.copyProperties(payloadInfo,userInfo);
                UserContext.setUser(userInfo);
            }
        }
        else {
           //判断是否是登录接口，登录接口正常走，非登录接口停
            List<String> loginUrl = config.urlPermissionConfig.getUrlPermissionList().stream()
                    .filter(res -> res.getType().equals(UrlPermissionConfig.Type.login.name()))
                    .collect(Collectors.toList()).stream()
                    .map(res -> {
                        return res.getUrl();
                    }).collect(Collectors.toList());
            if(loginUrl.size()>0){
                if(loginUrl.contains(request.getRequestURI().toString())){
                    loginFilter(token,body,response);
                }
                else {
                    Logger.info("未配置登录接口");
                }
            }

        }
    }


    void loginFilter(String token,JSONObject body,HttpServletResponse response){
        if(body==null){
            CustomException.errorToResponse(response,HttpStatus.BAD_REQUEST, REQUEST_ERROR);
        }
        String username = body.getString("username");
        String password = body.getString("password");
        if(username!=null && password!=null){
            boolean loginValid = loginValidAble.usernameAndPasswordValid(username, password);
            if(loginValid){
                // TODO: 2024/7/21 登录成功，存状态
                UserInfo userInfo = loginValidAble.getUserInfo(username,password);
                userInfo.getScopes().add("123");
                Instant now = Instant.now();
                Instant expireAt = now.plusSeconds(JwtUtil.expireInSec);
                token = JwtUtil.createToken(UUID.randomUUID().toString(), JwtUtil.SYS_NODE_CODE_KEY, userInfo,now,expireAt);
                userInfo.setToken(token);
                loginValidAble.saveUserInfo(userInfo);
            }
            if(!loginValid){
                //账号密码错误
                CustomException.errorToResponse(response,HttpStatus.BAD_REQUEST, USERORPASS_ERROR);
            }
        }
        else {
            CustomException.errorToResponse(response,HttpStatus.BAD_REQUEST, USERORPASS_ERROR);
        }
    }





}
